package com.nbcio.pm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nbcio.common.mybatis.core.page.PageQuery;
import com.nbcio.common.mybatis.core.page.TableDataInfo;
import com.nbcio.common.core.utils.MapstructUtils;
import com.nbcio.common.core.utils.StringUtils;
import com.nbcio.pm.domain.PmTeamPermission;
import com.nbcio.pm.domain.bo.PmTeamPermissionBo;
import com.nbcio.pm.domain.vo.PmTeamPermissionVo;
import com.nbcio.pm.mapper.PmTeamPermissionMapper;
import com.nbcio.pm.service.IPmTeamPermissionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 团队权限Service业务层处理
 *
 * @author nbacheng
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class PmTeamPermissionServiceImpl implements IPmTeamPermissionService {

    private final PmTeamPermissionMapper baseMapper;

    /**
     * 查询团队权限
     */
    @Override
    public PmTeamPermissionVo queryById(Long permissionId) {
        return baseMapper.selectVoById(permissionId);
    }

    /**
     * 查询团队权限列表
     */
    @Override
    public TableDataInfo<PmTeamPermissionVo> queryPageList(PmTeamPermissionBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PmTeamPermission> lqw = buildQueryWrapper(bo);
        Page<PmTeamPermissionVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询团队权限列表
     */
    @Override
    public List<PmTeamPermissionVo> queryList(PmTeamPermissionBo bo) {
        LambdaQueryWrapper<PmTeamPermission> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PmTeamPermission> buildQueryWrapper(PmTeamPermissionBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PmTeamPermission> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getPermissionName()), PmTeamPermission::getPermissionName, bo.getPermissionName());
        lqw.eq(StringUtils.isNotBlank(bo.getPermissionCode()), PmTeamPermission::getPermissionCode, bo.getPermissionCode());
        lqw.eq(StringUtils.isNotBlank(bo.getPermissionType()), PmTeamPermission::getPermissionType, bo.getPermissionType());
        lqw.eq(bo.getParentId() != null, PmTeamPermission::getParentId, bo.getParentId());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), PmTeamPermission::getStatus, bo.getStatus());
        lqw.orderByAsc(PmTeamPermission::getSortOrder);
        return lqw;
    }

    /**
     * 新增团队权限
     */
    @Override
    public Boolean insertByBo(PmTeamPermissionBo bo) {
        PmTeamPermission add = MapstructUtils.convert(bo, PmTeamPermission.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setPermissionId(add.getPermissionId());
        }
        return flag;
    }

    /**
     * 修改团队权限
     */
    @Override
    public Boolean updateByBo(PmTeamPermissionBo bo) {
        PmTeamPermission update = MapstructUtils.convert(bo, PmTeamPermission.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PmTeamPermission entity) {
        // 校验权限编码唯一性
        LambdaQueryWrapper<PmTeamPermission> lqw = Wrappers.lambdaQuery();
        lqw.eq(PmTeamPermission::getPermissionCode, entity.getPermissionCode());
        lqw.ne(entity.getPermissionId() != null, PmTeamPermission::getPermissionId, entity.getPermissionId());
        if (baseMapper.exists(lqw)) {
            throw new RuntimeException("权限编码已存在");
        }
    }

    /**
     * 批量删除团队权限
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // 校验权限是否被使用
            // TODO: 添加权限使用情况校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 根据权限编码查询权限
     */
    @Override
    public PmTeamPermissionVo queryByPermissionCode(String permissionCode) {
        return baseMapper.selectPmTeamPermissionByCode(permissionCode, "000000");
    }

    /**
     * 查询角色拥有的权限列表
     */
    @Override
    public List<PmTeamPermissionVo> queryPermissionsByRoleId(Long roleId) {
        return baseMapper.selectPermissionsByRoleId(roleId, "000000");
    }

    /**
     * 查询用户拥有的权限列表
     */
    @Override
    public List<PmTeamPermissionVo> queryPermissionsByUserId(Long userId) {
        return baseMapper.selectPermissionsByUserId(userId, "000000");
    }

    /**
     * 查询权限树结构
     */
    @Override
    public List<PmTeamPermissionVo> queryPermissionTree() {
        return baseMapper.selectPermissionTree("000000");
    }

    /**
     * 构建权限树
     */
    @Override
    public List<PmTeamPermissionVo> buildPermissionTree(List<PmTeamPermissionVo> permissions) {
        if (permissions == null || permissions.isEmpty()) {
            return new ArrayList<>();
        }

        // 按父ID分组
        Map<Long, List<PmTeamPermissionVo>> parentMap = permissions.stream()
                .collect(Collectors.groupingBy(PmTeamPermissionVo::getParentId));

        // 找到根节点（父ID为0或null的节点）
        List<PmTeamPermissionVo> rootNodes = parentMap.getOrDefault(0L, new ArrayList<>());
        if (rootNodes.isEmpty()) {
            rootNodes = permissions.stream()
                    .filter(p -> p.getParentId() == null || p.getParentId() == 0)
                    .collect(Collectors.toList());
        }

        // 递归构建树结构
        for (PmTeamPermissionVo root : rootNodes) {
            buildChildren(root, parentMap);
        }

        return rootNodes;
    }

    /**
     * 递归构建子节点
     */
    private void buildChildren(PmTeamPermissionVo parent, Map<Long, List<PmTeamPermissionVo>> parentMap) {
        List<PmTeamPermissionVo> children = parentMap.get(parent.getPermissionId());
        if (children != null && !children.isEmpty()) {
            parent.setChildren(children);
            for (PmTeamPermissionVo child : children) {
                buildChildren(child, parentMap);
            }
        }
    }
}
